/* lcd_port.c */

#include "fsl_gpio.h"
#include "fsl_spi.h"
#include "lcd_hx8347d.h"

#define GPIO_LCD_CS_PORT_IDX     1u
#define GPIO_LCD_CS_PIN_IDX      1u

#define GPIO_LCD_BL_PORT_IDX     1u
#define GPIO_LCD_BL_PIN_IDX      5u

#define GPIO_LCD_DC_PORT_IDX     1u
#define GPIO_LCD_DC_PIN_IDX      9u

#define GPIO_SDCARD_CS_PORT_IDX  1u
#define GPIO_SDCARD_CS_PIN_IDX   4u

#define GPIO_TOUCH_CS_PORT_IDX   1u
#define GPIO_TOUCH_CS_PIN_IDX    7u

// 软件模拟SPI
#define GPIO_SPI_CLK_PORT_IDX     1u
#define GPIO_SPI_CLK_PIN_IDX      2u

#define GPIO_SPI_TX_PORT_IDX      0u
#define GPIO_SPI_TX_PIN_IDX       26u

/* hardware spi */
/*
 * LSPI_SCK       PIO1_2
 * LSPI_MOSI      PIO0_26
 */

#define LCD_SPIx   SPI8 /* HS_LSPI. */

void __LCD_HW_INIT(void)
{
    spi_master_config_t spiMasterConfigStruct;
    gpio_pin_config_t   gpioPinConfig;

     /* GPIO Pins. */
    CLOCK_EnableClock(kCLOCK_Gpio0);
    CLOCK_EnableClock(kCLOCK_Gpio1);

    gpioPinConfig.pinDirection = kGPIO_DigitalOutput;
    gpioPinConfig.outputLogic  = 1u; /* output high as default. */

    GPIO_PinInit(GPIO, GPIO_LCD_CS_PORT_IDX, GPIO_LCD_CS_PIN_IDX, &gpioPinConfig);
    GPIO_PinInit(GPIO, GPIO_LCD_BL_PORT_IDX, GPIO_LCD_BL_PIN_IDX, &gpioPinConfig);
    GPIO_PinInit(GPIO, GPIO_LCD_DC_PORT_IDX, GPIO_LCD_DC_PIN_IDX, &gpioPinConfig);
    GPIO_PinInit(GPIO, GPIO_SDCARD_CS_PORT_IDX, GPIO_SDCARD_CS_PIN_IDX, &gpioPinConfig);
    GPIO_PinInit(GPIO, GPIO_TOUCH_CS_PORT_IDX, GPIO_TOUCH_CS_PIN_IDX, &gpioPinConfig);

    /* hardware spi. */
    CLOCK_SetClkDiv(kCLOCK_DivFrohfClk, 1U, false); /* FRO96M / 1. */
    CLOCK_AttachClk(kFRO_HF_DIV_to_HSLSPI); /* setup clock source from divided FRO_HF. */

    SPI_MasterGetDefaultConfig(&spiMasterConfigStruct);
    spiMasterConfigStruct.enableMaster = true;
    spiMasterConfigStruct.polarity     = kSPI_ClockPolarityActiveHigh;
    spiMasterConfigStruct.phase        = kSPI_ClockPhaseFirstEdge;
    spiMasterConfigStruct.direction    = kSPI_MsbFirst;
    spiMasterConfigStruct.baudRate_Bps = 48000000ul; /* 48MHz */
    SPI_MasterInit(LCD_SPIx, &spiMasterConfigStruct, CLOCK_GetFreq(kCLOCK_HsLspi));

}

void __flush_spi(void)
{
    volatile uint32_t i;

    while (0 == (LCD_SPIx->FIFOSTAT & SPI_FIFOSTAT_TXEMPTY_MASK))
    {
    }
    while ((LCD_SPIx->STAT & SPI_STAT_MSTIDLE_MASK) == 0)
    {
    }
}

/* 背光 */
void __LCD_BKL_SET(void)
{
    __flush_spi();
    GPIO_PinWrite(GPIO, GPIO_LCD_BL_PORT_IDX, GPIO_LCD_BL_PIN_IDX, 1u);
}

/* 片选信号拉低 */
void __LCD_CS_CLR(void)
{
    __flush_spi();
    GPIO_PinWrite(GPIO, GPIO_LCD_CS_PORT_IDX, GPIO_LCD_CS_PIN_IDX, 0u);
}

/* 片选信号拉高,放开片选 */
void __LCD_CS_SET(void)
{
    __flush_spi();/* 等待数据发送完成 */
    GPIO_PinWrite(GPIO, GPIO_LCD_CS_PORT_IDX, GPIO_LCD_CS_PIN_IDX, 1u);
}

/* 数据命令信号拉低 */
void __LCD_DC_CLR(void)
{
    __flush_spi();
    GPIO_PinWrite(GPIO, GPIO_LCD_DC_PORT_IDX, GPIO_LCD_DC_PIN_IDX, 0u);
}

/* 数据命令信号拉高 */
void __LCD_DC_SET(void)
{
    __flush_spi();
    GPIO_PinWrite(GPIO, GPIO_LCD_DC_PORT_IDX, GPIO_LCD_DC_PIN_IDX, 1u);
}

void __LCD_WRITE_BYTE(uint8_t txDat)
{
    //LCD_SPIx->FIFOCFG |= SPI_FIFOCFG_EMPTYRX_MASK; /* clear rx fifo. */
    while ((LCD_SPIx->FIFOSTAT & SPI_FIFOSTAT_TXNOTFULL_MASK) == 0)
    {}
    LCD_SPIx->FIFOSTAT = SPI_FIFOSTAT_TXERR_MASK | SPI_FIFOSTAT_RXERR_MASK;
    LCD_SPIx->FIFOWR = txDat | 0x07700000;
}


volatile uint32_t vu32DelayCount;

void __LCD_delay_ms(uint32_t dlyMs)
{
    for (vu32DelayCount = 0u; vu32DelayCount < 150 * dlyMs; vu32DelayCount++)
    {
        __NOP();
    }
}

void lcd_fill_screen_dma(uint16_t hwXpos, uint16_t hwYpos, uint8_t *datBuf)
{

}

/* EOF. */

